<template>
    <div class="box">
        <h1>slot-插槽讲解</h1>
        <!-- 插槽的介绍 -->
        <Child :obj="obj">
            你演的电视剧太好看
        </Child>

        <!-- 插槽的使用 -->
        <Child :obj="obj">
            <template v-slot:default>
                这是默认插槽的传入文本
            </template>
            <template v-slot:abc>
                父组件传的具名插槽的文本呢
            </template>
            <template v-slot:qwer="xxx">
                <div class="box">
                    <div>{{ xxx }}</div>
                    <h4>父组件中也要展示name和intro</h4>
                    <div>name: {{ xxx.nickname }}</div>
                    <div>intro: {{ xxx.intro }}</div>
                </div>
            </template>
        </Child>

        <br><br>

        <!--
            1.当只有一个插槽的时候可以把 template 省略掉

            2.v-slot:qwer="scope"
            冒号后面跟的是qwer是name属性,子组件没有name属性,此时就可以把:qwer省略掉
            直接使用 v-slot="scope"
        -->
        <Child2 :obj="obj" v-slot="scope">
            <h4>随便写</h4>
            <div>nickname: {{ scope.nickname }}</div>
            <div>intro: {{ scope.intro }}</div>
            <div>text: {{ scope.text }}</div>
        </Child2>

        <!-- 当然,这里还能简化 - 解构子组件slot标签传过来的数据 -->
        <Child2 :obj="obj" v-slot="{ nickname, intro, text }">
            <h4>随便写</h4>
            <div>nickname: {{ nickname }}</div>
            <div>intro: {{ intro }}</div>
            <div>text: {{ text }}</div>
        </Child2>
    </div>
</template>

<script>
// slot使插槽
// 什么是插槽?
//      之前的做法,使用子组件的时候,通过数据来决定子组件的渲染
//      有了插槽之后,在子组件中开一个槽,这个槽当中的内容(模板)可以由外部决定
//      什么是插槽? 父子组件间的一种通信方式,父组件可以决定子组件中的模板
// 为什么使用插槽?
//      在很多情况下我们需要封装一个公共组件,公共组件中的内容有些是确定的,可以由数据来渲染
//      而有些时候(别人想要用当前组件的时候,并且使用组件的时候,其中某块样式结构和封装的组件不一样)
//      此时使用插槽刚好合适
//      说白了: 插槽是组件内部的某一块 结构(html)和样式(css)不能确定,需要父组件来决定的时候,使用插槽
// 如何使用插槽?
//      1. 子组件中使用 slot 标签
//          相当于在子组件当中开了个槽,slot标签中的内容可以自己写,默认slot会被渲染去展示
//      2. 父组件中使用子组件的标签之间可以写内容
//          子组件标签之间写的内容将会被渲染到子组件中的 slot 标签的位置
// 这仅仅是最简单的使用方式
// 插槽总共分为三类: 默认插槽、具名插槽、作用域插槽 - 刚刚我们写的是默认插槽,并且是简写
// 默认插槽:
//      子组件
//          <slot></slot>
//      父组件
//          <Child>
//              <template v-slot:default>
//                  这是默认插槽的传入文本
//              </template>
//          </Child>
//          完整版,当子组件中有且仅有一个插槽的时候,简写是ok的
//          <Child>
//              你演的电视剧太好看
//          </Child>
//      此时如果子组件中再来一个slot标签,会把父组件中子组件标签中间的文本,插入的子组件的slot标签,有几个slot标签,就会重复几次
//      我们期望: 子组件再渲染父组件传过来的模板的时候,渲染到特定的位置,不能每个位置都渲染同一块内容
// 具名插槽
//      具有名称的插槽叫具名插槽
//      子组件
//          <slot name="abc"></slot>
//      父组件
//          <Child>
//              <template v-slot:default>
//                  这是默认插槽的传入文本
//              </template>
//              <template v-slot:abc>
//                  父组件传的具名插槽的文本呢
//              </template>
//          </Child>
//          v-slot:abc 这个 template 中的内容将会渲染到子组件的具名插槽abc中
// 作用域插槽
//      父组件可以把数据传递给子组件,什么情况下会用到作用域插槽呢?
//      当父组件需要决定子组件中模板的结构的时候,此时用到slot(默认插槽或具名插槽)
//      如果父组件决定子组件中模板结构【需要】用到子组件中的数据的时候,此时用到作用域插槽
//      怎么做?
//      1. 子组件slot标签上写属性
//          除了name属性之外的属性,都会收集起来组成一个对象交给父组件设置的插槽指令后面
//      2. 父组件写插槽内容的时候加 v-slot 指令可以获取到子组件传过来的数据
//          v-slot:qwer="xxx"
//          v-slot是vue的指令
//          :qwer 的 qwer 是插槽的name属性,插槽的名称
//          ="xxx" 等号后面的 xxx 是子组件绑定在 slot 标签上的属性组成的对象
import Child from './Child'
import Child2 from './Child2'
export default {
    name: "SlotTest",
    components: { Child, Child2 },
    data() {
        return {
            obj: {
                name: '赵四',
                intro: '大米是饭前吃还是饭后吃'
            }
        }
    }
}
</script>

<style scoped>

</style>